package com.jdd.fintech.morse.plugin.strategy;

import com.alibaba.fastjson.JSONObject;
import com.jd.fastjson.JSON;
import com.jdd.fintech.morse.plugin.ecrypts.SymmetricCrypto;
import com.jdd.fintech.morse.plugin.enums.BizErrorCodeEnum;
import com.jdd.fintech.morse.plugin.enums.BooleanEnum;
import com.jdd.fintech.morse.plugin.enums.CustomVersionEnum;
import com.jdd.fintech.morse.plugin.plugconfig.MorsePlugValueConfig;
import com.jdd.fintech.morse.plugin.strategy.context.AbstractDataEncryptAndDecryptStrategy;
import com.jdd.fintech.morse.plugin.util.CommonMethodUtils;
import com.jdd.fintech.morse.plugin.util.JsonStringUtils;
import com.jddglobal.filter.support.exception.FilterException;
import com.jddglobal.phevos.gateway.resources.ResourceCapability;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.ObjectUtils;

import java.nio.charset.StandardCharsets;

import static com.jdd.fintech.morse.plugin.constans.OpenApiConstans.*;
import static com.jdd.fintech.morse.plugin.util.RSAUtil.*;

/**
 * @类描述: 云工厂数据加密策略类
 * @类名称: YgcDataEncryptAndDecryptStrategy
 * @操作人: ext.fengcheng
 * @操作时间: 2022/10/20 14:37
 * @类全路径: com.jdd.fintech.morse.plugin.strategy.YgcDataEncryptAndDecryptStrategy
 * @项目名称:
 **/
public class YgcDataEncryptAndDecryptStrategy extends AbstractDataEncryptAndDecryptStrategy {

    /**
     * 数据加密策略接口方法(云工厂使用)
     *
     * @param plugValueConfig 插件值对象
     * @param jsonObject      请求对象
     * @param scObj           算法对象
     * @return
     */
    @Override
    public String dataEncryptsStrategyMethod(MorsePlugValueConfig plugValueConfig, JSONObject jsonObject, SymmetricCrypto scObj) throws FilterException {
        log.info("YgcDataEncryptAndDecryptStrategy.dataEncryptsStrategyMethod.云工厂的价签加密操作---处理开始");
        String jsonString = jsonObject.toJSONString();
        try {
            JSONObject extendParameter = JSONObject.parseObject(plugValueConfig.getExtendParameter());
            //获取请求报文中 业务数据的KEY
            String messageBizDateKey = CommonMethodUtils.getMessageBizDateKey(plugValueConfig);
            log.info("YgcDataEncryptAndDecryptStrategy.asymmetricEncrypts.非对称式加密=====处理开始");
            //声明密文字符串
            String ciphertext;
            //网贷密码
            String wdPassword = plugValueConfig.getSalt();
            //云工厂公钥，用作加密
            String ygcPublicSecurity = plugValueConfig.getPublicSecurity();
            //网贷秘钥，用作加签
            String wdPrivateKeys = extendParameter.getString(WD_PRIVATE_KEY);
            CustomVersionEnum customVersion = plugValueConfig.getCustomVersion();
            //判断是否完整加解密
            if (BooleanEnum.YES.name().equals(plugValueConfig.getIsComplete().getCode())) {
                ciphertext = wyaksRsaEncrypt(wdPrivateKeys, wdPassword, ygcPublicSecurity, jsonString, customVersion);
            } else {
                //获取业务报文数据对象
                String bizMsgObj = jsonObject.getString(messageBizDateKey);
                if (ObjectUtils.isEmpty(bizMsgObj)) {
                    return jsonObject.toJSONString();
                }
                ciphertext = wyaksRsaEncrypt(wdPrivateKeys, wdPassword, ygcPublicSecurity, bizMsgObj, customVersion);
            }
            jsonObject.put(messageBizDateKey, ciphertext);
        } catch (Exception e) {
            log.error("YgcDataEncryptAndDecryptStrategy.dataEncryptsStrategyMethod.云工厂.非对称式加密|明文参数|jsonObject：{}", jsonString);
            log.error("YgcDataEncryptAndDecryptStrategy.dataEncryptsStrategyMethod.云工厂.非对称式加密|插件值参数|plugValueConfig：{}", JSONObject.toJSONString(plugValueConfig));
            log.error("YgcDataEncryptAndDecryptStrategy.dataEncryptsStrategyMethod.云工厂.非对称式加密|加密异常|异常信息：{}", e.getMessage(), e);
            throw new FilterException(new ResourceCapability.AutoDefineResource(BizErrorCodeEnum.FAILURE_3.getCode(), BizErrorCodeEnum.FAILURE_3.getDesc()));
        }
        log.info("YgcDataEncryptAndDecryptStrategy.asymmetricEncrypts.非对称式加密=====处理结束");
        return jsonObject.toJSONString();
    }

    /**
     * 数据解密策略接口方法(云工厂使用)
     *
     * @param plugValueConfig 插件值对象
     * @param jsonObject      请求对象
     * @param scObj           算法对象
     * @return
     * @throws FilterException 方法
     */
    @Override
    public String dataDecryptsStrategyMethod(MorsePlugValueConfig plugValueConfig, JSONObject jsonObject, SymmetricCrypto scObj) throws FilterException {
        log.info("YgcDataEncryptAndDecryptStrategy.dataEncryptsStrategyMethod.云工厂的验签解密操作---处理开始");
        String jsonString = jsonObject.toJSONString();
        try {
            //获取请求报文中 业务数据的KEY
            String messageBizDateKey = CommonMethodUtils.getMessageBizDateKey(plugValueConfig);
            //密文字符串
            String ciphertext = jsonObject.getString(messageBizDateKey);
            //解密后的明文
            String plaintext = "";
            //判断是否完整加解密
            if (BooleanEnum.YES.name().equals(plugValueConfig.getIsComplete().getCode())) {
                plaintext = asymmetricDecryption(plugValueConfig, jsonString);
            } else {
                // 如果密文不为 null 则需要进行验签和解密
                if (StringUtils.isNotBlank(ciphertext)) {
                    plaintext = asymmetricDecryption(plugValueConfig, ciphertext);
                }
            }
            jsonObject.put(messageBizDateKey, plaintext);
        } catch (Exception e) {
            log.error("YgcDataEncryptAndDecryptStrategy.dataDecryptsStrategyMethod.云工厂.非对称式解密|密文参数|jsonObject：{}", jsonString);
            log.error("YgcDataEncryptAndDecryptStrategy.dataDecryptsStrategyMethod.云工厂.非对称式验签解密|解密异常|异常信息：{}", e.getMessage(), e);
            throw new FilterException(new ResourceCapability.AutoDefineResource(BizErrorCodeEnum.FAILURE_4.getCode(), BizErrorCodeEnum.FAILURE_4.getDesc()));
        }
        log.info("YgcDataEncryptAndDecryptStrategy.dataDecryptsStrategyMethod.云工厂.非对称式验签解密=====处理结束");
        return null;
    }

    /**
     * @方法描述: 开始进行解密处理
     * @方法名称: YgcDataEncryptAndDecryptStrategy.asymmetricDecryption
     * @方法操作人: ext.fengcheng
     * @方法生成时间: 2022/10/27 10:32
     * @方法执行参数: [plugValueConfig(插件值对象), ciphertext(密文)]
     * @方法返回参数: java.lang.String
     * @方法产生异常:
     **/
    public String asymmetricDecryption(MorsePlugValueConfig plugValueConfig, String ciphertext) throws FilterException {
        log.info("YgcDataEncryptAndDecryptStrategy.asymmetricDecryption.云工厂.非对称式验签解密=====处理开始");
        String plaintext = "";
        byte[] plaintextArray = null;
        String saltwd = plugValueConfig.getSalt();
        String privateSecurity = plugValueConfig.getPrivateSecurity();
        CustomVersionEnum customVersion = plugValueConfig.getCustomVersion();
        try {
            //判断是否是文件，然后开始进行解密操作
            if (BooleanEnum.YES.getCode().equals(plugValueConfig.getIsFile().getCode())) {
                plaintextArray = wyaksRsaDecrypt(privateSecurity, saltwd, ciphertext, customVersion);
                if (null != plaintextArray) {
                    plaintext = Base64.encodeBase64String(plaintextArray);
                }
            } else {
                plaintextArray = wyaksRsaDecrypt(privateSecurity, saltwd, ciphertext, customVersion);
                if (null != plaintextArray) {
                    plaintext = new String(plaintextArray, StandardCharsets.UTF_8);
                }
            }
        } catch (Exception e) {
            log.error("YgcDataEncryptAndDecryptStrategy.asymmetricDecryption.云工厂.非对称式验签解密|解密异常|ciphertext：{} 异常信息：{}", ciphertext, e.getMessage(), e);
            throw new FilterException(new ResourceCapability.AutoDefineResource(BizErrorCodeEnum.FAILURE_4.getCode(), BizErrorCodeEnum.FAILURE_4.getDesc()));
        }
        log.info("YgcDataEncryptAndDecryptStrategy.asymmetricDecryption.云工厂.非对称式验签解密=====处理结束");
        return plaintext;
    }


    /**
     * 构建公共请求对象(云工厂使用)
     *
     * @param plugValueConfig
     * @param tenantId
     * @param productCode
     * @param jsonObject
     * @return
     */
    @Override
    public String buildCommonRequestObjMethod(MorsePlugValueConfig plugValueConfig, String tenantId, String productCode, JSONObject jsonObject) throws FilterException {
        String messageBizDateKey = CommonMethodUtils.getMessageBizDateKey(plugValueConfig);
        log.info("YgcDataEncryptAndDecryptStrategy.buildCommonRequestObjMethod.云工厂---构建响应数据======>开始");
        //判断是否是JSON,如果不是直接返回原始json字符串
        if (!JsonStringUtils.judgeIsJson(messageBizDateKey, jsonObject)) {
            return jsonObject.toJSONString();
        }
        try {
            //构建响应数据
            JSONObject jsonRequestData = JSON.parseObject(jsonObject.getString(messageBizDateKey).trim(), JSONObject.class);
            jsonRequestData.put("productCode", productCode);
            jsonRequestData.put("tenantId", tenantId);
            jsonObject.put(messageBizDateKey, jsonRequestData.toJSONString());
            jsonObject.remove(YGC_SIGN);
            log.info("YgcDataEncryptAndDecryptStrategy.buildCommonRequestObjMethod.云工厂---构建响应数据======>结束");
            return jsonObject.toJSONString();
        } catch (Exception e) {
            log.error("YgcDataEncryptAndDecryptStrategy.dataDecryptsStrategyMethod.云工厂|数据格式错误，转换失败|解密后的数据|jsonObject:{}|异常信息：{}", jsonObject.toJSONString(), e.getMessage(), e);
            return jsonObject.toJSONString();
        }
    }
}
